package com.doeis.minaserver.handler;

import java.sql.Timestamp;

import com.doeis.log.QueueManager;
import com.doeis.minaserver.NettyServer;
import com.doeis.minaserver.module.PacketRouter;
import com.doeis.minaserver.packet.InfoPacket;
import com.doeis.minaserver.packet.Packet;
import com.doeis.minaserver.packet.Packet.PacketType;
import com.doeis.minaserver.session.ClientConnection;
import com.doeis.uwork.entity.mongo.MethodLog;
import com.doeis.uwork.packet.GroupMsgPacket;
import com.doeis.uwork.packet.MessagePacket;
import com.doeis.uwork.packet.PrivateMsgPacket;
import com.doeis.uwork.packet.SystemPacket;
import com.voland.core.utils.DateUtils;
import com.voland.core.utils.IDGenerator;

/**
 * 数据包总处理类，从ConnectionHandler类传递过来的数据已经具有具体的数据包类型
 * 
 * @author nortan
 * 
 */
public class PacketHandler {

	PacketRouter packetRouter;
	
	public PacketHandler(PacketRouter packetRouter) {
		this.packetRouter = packetRouter;
	}

	public void process( Packet packet, ClientConnection clientConn,  NettyServer server) {
		long start = System.currentTimeMillis();
		//监控业务操作时间
		processThread(packet, clientConn);
		
		MethodLog methodLog = new MethodLog();
		methodLog.setFirstTime(new Timestamp(start) );
		methodLog.setCreateTime(DateUtils.currentDateTime() );
		methodLog.setId(IDGenerator.uuid() );
		methodLog.setMethod("process" );
		methodLog.setParameter(packet.toString() );
		methodLog.setUser_id(clientConn.getUserid() );
		methodLog.setUseTime( System.currentTimeMillis()-start );
		QueueManager queueManager = server.getT(QueueManager.class);
		if(queueManager!=null){
			queueManager.sendLog(methodLog);
		}
		
//		clientConn.getNioServiceEventLoop().execute(new Runnable() {
//			@Override
//			public void run() {
//				processThread(packet, clientConn);
//			}
//		});
	}
	
	public void processThread(Packet packet, ClientConnection clientConn) {
		String from = packet.getFrom();
		// 首先判断一下用户是否已经登陆（登陆包不需要判断）
		if (packet.getCmd() != InfoPacket.CMD_USER_LOGIN 
				&& packet.getCmd() != InfoPacket.CMD_SHUTDOWN_SERVER) {
			// 如果为非登陆操作,则数据包需要判断这个包的发送人是否已经登陆
			if (from.equals(Packet.WEB_SERVER_ID)) {
				
			}else if (!isLogin(from, clientConn) || !isOwerPacket(from, clientConn) ) {
				System.out.println(from+"  没有登陆");
				return;
			}
		}

		PacketType type = packet.getPacketType();
		switch (type) {
		case info: {
			InfoPacket p = (InfoPacket) packet;
			packetRouter.route(clientConn, p);
			break;
		}
		case message: {
			MessagePacket p = (MessagePacket) packet;
			packetRouter.route(clientConn, p);
			break;
		}
		case groupMsg: {
			GroupMsgPacket p = (GroupMsgPacket) packet;
			packetRouter.route(clientConn, p);
			break;
		}
		case privateMsg: {
			PrivateMsgPacket p = (PrivateMsgPacket) packet;
			packetRouter.route(clientConn, p);
			break;
		}
		case system: {
			SystemPacket p = (SystemPacket) packet;
			packetRouter.route(clientConn, p);
			break;
		}

		default:
			break;
		}
	}

	/**
	 * 判断用户是否已经登录
	 * 
	 * @param phoneid
	 * @return
	 */
	private boolean isLogin(String userid, ClientConnection clientConn) {
		return clientConn.getStatus() == ClientConnection.STATUS_LOGIN;
	}

	/**
	 * 判断出用户是否为伪用户（封装成别人的信息包）
	 */
	private boolean isOwerPacket(String userid, ClientConnection clientConn) {
		return clientConn.getUserid().equals(userid);
	}

	/**
	 * 判断用户是否在线
	 * 
	 * @param clientConn
	 * @return
	 */
	public boolean isOnline(ClientConnection clientConn) {
		return clientConn != null && !clientConn.isClosed()
				&& clientConn.getStatus() == ClientConnection.STATUS_LOGIN;
	}
}
